package stream;

import org.junit.Test;
import ref.Employee;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author com.alibaba.lizhen
 * @Date 2021/3/24 11:05 上午
 * @Version 1.0
 * @Description
 *  * 创建stream
 *  * 中间操作（过滤、map）
 *  * 终止操作
 */
public class StreamApiTest4 {


    /**
     *
     * Stream终止操作：
     * 归约 / 收集
     *      归约：reduce(T identity, BinaryOperator) / reduce(BinaryOperator) 可以将流中的数据反复结合起来，得到一个值
     *      收集：collect 将流转换成其他形式；接收一个 Collector 接口的实现，用于给流中元素做汇总的方法
     */
    @Test
    public void test6(){
        /**
         * case1 ： 有初始值，肯定不是JNP
         */
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Integer integer = list.stream()
                //第一个参数是初始值，后面是迭代的规则
                .reduce(0, (x, y) -> x + y);
//                .reduce(0, Integer::sum);
        System.out.println(integer);

        /**
         * case2:无初始值，有可能JNP，所以用Option封装
         */
        Optional<Integer> reduce = emps.stream()
                //map -reduce 操作，过滤，规约
                .map(Employee::getId)
                .reduce(Integer::sum);
        System.out.println(reduce.orElse(-1));
    }

    /**
     *  收集：collect 将流转换成其他形式；接收一个 Collector 接口的实现，用于给流中元素做汇总的方法
     *
     *  collect函数的参数是 Collector<? super T, A, R> collector 接口，
     *  其有静态实现类 Collectors
     */

    List<Employee> emps = Arrays.asList(
            new Employee(1, "张三1"),
            new Employee(1, "张三2"),
            new Employee(2, "张三1"),
            new Employee(2, "张三2"),
            new Employee(3, "张三3"),
            new Employee(4, "张三4"),
            new Employee(5, "张三5"),
            new Employee(6, "张三6"),
            new Employee(7, "张三7")
    );
    @Test
    public void test02(){
        //放入List
        List<String> list = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());
        list.forEach(System.out::println);


        //放入Set
        Set<String> set = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toSet());
        set.forEach(System.out::println);

        //放入LinkedHashSet
        LinkedHashSet<String> linkedHashSet = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(LinkedHashSet::new));
        linkedHashSet.forEach(System.out::println);

        //放入map
        Map<Integer, String> map = emps.stream()
                .collect(Collectors.toMap(Employee::getId, Employee::getName));
        System.out.println("map = " + map);
    }

    @Test
    public void test03(){
        //总数
        Long count = emps.stream()
                .collect(Collectors.counting());
        System.out.println(count);

        //平均值
        Double avg = emps.stream()
                .collect(Collectors.averagingDouble(Employee::getId));
        System.out.println(avg);

        //总和
        Long sum = emps.stream()
                .collect(Collectors.summingLong(Employee::getId));
//        Long sum = emps.stream().mapToLong(Employee::getId).sum();
        System.out.println(sum);

        //最大值
        Optional<Employee> max = emps.stream()
                .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getId(), e2.getId())));
        System.out.println(max.get());

    }

    @Test
    public void test04(){
        //分组
        Map<Integer, List<Employee>> map = emps.stream()
                .collect(Collectors.groupingBy(Employee::getId));
        System.out.println(map);

        //多级分组
        Map<Integer, Map<String, List<Employee>>> mapMap = emps.stream()
                .collect(Collectors.groupingBy(Employee::getId, Collectors.groupingBy((e) -> {
                    if (e.getName().equals("张三1")) {
                        return "张三1";
                    } else {
                        return "张三2";
                    }
                })));
        System.out.println(mapMap);

        //分区
        Map<Boolean, List<Employee>> listMap = emps.stream()
                .collect(Collectors.partitioningBy((e) -> e.getId() > 4));
        System.out.println(listMap);
    }

    @Test
    public void test05(){
        //总结
        DoubleSummaryStatistics dss = emps.stream()
                .collect(Collectors.summarizingDouble(Employee::getId));
        System.out.println(dss.getMax());
        System.out.println(dss.getMin());
        System.out.println(dss.getSum());
        System.out.println(dss.getCount());
        System.out.println(dss.getAverage());


        List<String> list = Arrays.asList("a","b","c");
        //连接
        String str = list.stream()
                .collect(Collectors.joining("-","{","}")); //可传入分隔符
        System.out.println(str);
    }


}
